using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Threading;

namespace cb0tServer
{
    class Settings
    {
        private static Mutex mutex = new Mutex();

        public static bool general = true;
        public static bool admins = true;
        public static bool stealth = false;
        public static bool clock = false;
        public static bool idle = true;
        public static bool greet = false;
        public static String greetmsg2 = String.Empty;
        public static bool pmgreet = false;
        public static String pmgreetmsg = String.Empty;
        public static bool caps = false;
        public static bool anon = false;
        public static bool sharefiles = false;
        public static bool filter = false;
        public static bool customname = false;
        public static bool adminannounce = false;
        public static bool colors = true;
        public static ushort mtimeout = 0;
        public static bool last_seen = false;
        public static bool room_info = false;
        public static String host_status = "Here :-)";
        public static bool silenced = false;

        public static List<ushort> locked_vrooms = new List<ushort>();
        public static List<String> pm_block = new List<String>();
        public static List<DUrlObject> durlmsg = new List<DUrlObject>();
        public static bool durl = false;

        public static bool dtopic = false;
        public static String dtopicmsg = String.Empty;

        public static bool allow_history = true;

        public static void ViewGreetMsg(UserObject userobj)
        {
            String greetmsg = Greetings.NextMessage;

            if (greetmsg == null)
                return;

            UserObject u = UserPool.RandomUser();
            String rnd_user = u == null ? userobj.name : u.name;
            String str = greetmsg;

            String _str = Helpers.CountryCodeToString(userobj.user_country);

            if (_str != "?")
                if (userobj.user_region.Length > 0)
                    _str = userobj.user_region + ", " + _str;

            if (_str == "?")
                if (userobj.user_region.Length > 0)
                    _str = userobj.user_region;

            if (_str == "?")
                _str = "unknown";

            str = str.Replace("+n", userobj.name); // user's name
            str = str.Replace("+ip", userobj.physical_ip.ToString()); // user's external ip
            str = str.Replace("+id", userobj.id.ToString()); // user's ident
            str = str.Replace("+f", userobj.files.ToString()); // user's file count
            str = str.Replace("+v", userobj.version); // user's client version
            str = str.Replace("+p", userobj.dc_port.ToString()); // user's dc port
            str = str.Replace("+uc", UserPool.UserCount().ToString()); // user count
            str = str.Replace("+rn", CoreSettings.room_name); // room name
            str = str.Replace("+ut", Stats.GetUptime()); // server uptime
            str = str.Replace("+ru", rnd_user); // random username
            str = str.Replace("+l", _str); // location
            UserPool.Broadcast(userobj.vroom, ServerOutboundPackets.AnnoucePacket(str));
        }

        public static void ViewPMGreetMsg(UserObject userobj)
        {
            if (pmgreetmsg.Length == 0) return;
            UserObject u = UserPool.RandomUser();
            String rnd_user = u == null ? userobj.name : u.name;
            String str = pmgreetmsg;

            String _str = Helpers.CountryCodeToString(userobj.user_country);

            if (_str != "?")
                if (userobj.user_region.Length > 0)
                    _str = userobj.user_region + ", " + _str;

            if (_str == "?")
                if (userobj.user_region.Length > 0)
                    _str = userobj.user_region;

            if (_str == "?")
                _str = "unknown";

            str = str.Replace("+n", userobj.name);
            str = str.Replace("+ip", userobj.physical_ip.ToString());
            str = str.Replace("+id", userobj.id.ToString());
            str = str.Replace("+f", userobj.files.ToString());
            str = str.Replace("+v", userobj.version);
            str = str.Replace("+p", userobj.dc_port.ToString());
            str = str.Replace("+uc", UserPool.UserCount().ToString());
            str = str.Replace("+rn", CoreSettings.room_name);
            str = str.Replace("+ut", Stats.GetUptime());
            str = str.Replace("+ru", rnd_user);
            str = str.Replace("+l", _str);
            userobj.SendOutboundPacket(ServerOutboundPackets.PMPacket(CoreSettings.room_bot, str));
        }

        public static void Load()
        {
            mtimeout = 0;
            colors = true;
            silenced = false;

            if (!File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/server.xml")) return;

            try
            {
                FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/server.xml", FileMode.Open);
                XmlReader xml = XmlReader.Create(new StreamReader(f));

                xml.MoveToContent();
                xml.ReadSubtree().ReadToFollowing("server");
                xml.ReadToFollowing("settings");
                xml.ReadSubtree().ReadToFollowing("general");
                general = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("admins");
                admins = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("stealth");
                stealth = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("clock");
                clock = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("colors");
                colors = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("mtimeout");
                mtimeout = ushort.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("idle");
                idle = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("greet");
                greet = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("pmgreet");
                pmgreet = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("caps");
                caps = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("anon");
                anon = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("sharefiles");
                sharefiles = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("filter");
                filter = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("customname");
                customname = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("adminannounce");
                adminannounce = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("pmblock");
                byte[] tmp = Convert.FromBase64String(xml.ReadElementContentAsString());
                String str = Encoding.UTF8.GetString(tmp);
                pm_block = new List<String>(str.Split(new String[] { "\0" }, StringSplitOptions.RemoveEmptyEntries));
                xml.ReadToFollowing("greetmsg");
                greetmsg2 = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                xml.ReadToFollowing("pmgreetmsg");
                pmgreetmsg = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                xml.ReadToFollowing("locked");
                tmp = Convert.FromBase64String(xml.ReadElementContentAsString());
                locked_vrooms = new List<ushort>();
                List<byte> b = new List<byte>(tmp);

                while (b.Count > 1)
                {
                    locked_vrooms.Add(BitConverter.ToUInt16(b.ToArray(), 0));
                    b.RemoveRange(0, 2);
                }

                xml.ReadToFollowing("lastseen");
                last_seen = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("roominfo");
                room_info = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("hoststatus");
                host_status = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                xml.ReadToFollowing("dtopic");
                dtopic = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("dtopicmsg");
                dtopicmsg = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));

                xml.ReadToFollowing("durlmsg");
                String[] str_split = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString())).Split(new String[] { "\0" }, StringSplitOptions.None);
                durlmsg = new List<DUrlObject>();

                if (str_split.Length > 1)
                {
                    for (int i = 0; i < str_split.Length; i++)
                    {
                        DUrlObject d = new DUrlObject();
                        d.address = str_split[i];
                        d.text = str_split[i + 1];
                        i++;
                        durlmsg.Add(d);
                    }
                }

                xml.ReadToFollowing("durl");
                durl = bool.Parse(xml.ReadElementContentAsString());
                xml.ReadToFollowing("allow_history");
                allow_history = bool.Parse(xml.ReadElementContentAsString());

                xml.Close();
                f.Flush();
                f.Close();
            }
            catch { }
        }

        public static void Save()
        {
            mutex.WaitOne();

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/server.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("server");
                xml.WriteStartElement("settings");
                xml.WriteElementString("general", general.ToString());
                xml.WriteElementString("admins", admins.ToString());
                xml.WriteElementString("stealth", stealth.ToString());
                xml.WriteElementString("clock", clock.ToString());
                xml.WriteElementString("colors", colors.ToString());
                xml.WriteElementString("mtimeout", mtimeout.ToString());
                xml.WriteElementString("idle", idle.ToString());
                xml.WriteElementString("greet", greet.ToString());
                xml.WriteElementString("pmgreet", pmgreet.ToString());
                xml.WriteElementString("caps", caps.ToString());
                xml.WriteElementString("anon", anon.ToString());
                xml.WriteElementString("sharefiles", sharefiles.ToString());
                xml.WriteElementString("filter", filter.ToString());
                xml.WriteElementString("customname", customname.ToString());
                xml.WriteElementString("adminannounce", adminannounce.ToString());
                String str = String.Join("\0", pm_block.ToArray());
                str = Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
                xml.WriteElementString("pmblock", str);
                xml.WriteElementString("greetmsg", Convert.ToBase64String(Encoding.UTF8.GetBytes(greetmsg2)));
                xml.WriteElementString("pmgreetmsg", Convert.ToBase64String(Encoding.UTF8.GetBytes(pmgreetmsg)));
                List<byte> b = new List<byte>();

                foreach (ushort u in locked_vrooms)
                    b.AddRange(BitConverter.GetBytes(u));

                xml.WriteElementString("locked", Convert.ToBase64String(b.ToArray()));
                xml.WriteElementString("lastseen", last_seen.ToString());
                xml.WriteElementString("roominfo", room_info.ToString());
                xml.WriteElementString("hoststatus", Convert.ToBase64String(Encoding.UTF8.GetBytes(host_status)));
                xml.WriteElementString("dtopic", dtopic.ToString());
                xml.WriteElementString("dtopicmsg", Convert.ToBase64String(Encoding.UTF8.GetBytes(dtopicmsg)));

                String blah = "";

                foreach (DUrlObject d in durlmsg)
                    blah += d.address + "\0" + d.text + "\0";

                if (blah.Length > 0)
                    blah = blah.Substring(0, blah.Length - 1);

                xml.WriteElementString("durlmsg", Convert.ToBase64String(Encoding.UTF8.GetBytes(blah)));
                xml.WriteElementString("durl", durl.ToString());
                xml.WriteElementString("allow_history", allow_history.ToString());
                xml.WriteEndElement();
                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }
            
            mutex.ReleaseMutex();
        }
    }

    class DUrlObject
    {
        public String address;
        public String text;
    }
}
